package com.xhtt.modules.app.controller.cfg;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xhtt.common.exception.RRException;
import com.xhtt.common.exception.RRExceptionEnum;
import com.xhtt.common.utils.*;
import com.xhtt.modules.app.annotation.Login;
import com.xhtt.modules.app.annotation.LoginUser;
import com.xhtt.modules.cfg.entity.CfgPumpInfo;
import com.xhtt.modules.cfg.entity.CfgTubeInfo;
import com.xhtt.modules.cfg.entity.CfgTubeProduct;
import com.xhtt.modules.cfg.entity.CfgTubeRelate;
import com.xhtt.modules.cfg.model.ValidTubeParam;
import com.xhtt.modules.cfg.service.CfgTubeInfoService;
import com.xhtt.modules.cfg.service.CfgTubeProductService;
import com.xhtt.modules.cfg.service.CfgTubeRelateService;
import com.xhtt.modules.sys.controller.AbstractController;
import com.xhtt.modules.sys.entity.SysUserEntity;
import com.xhtt.modules.task.entity.TaskShipTaskLm;
import com.xhtt.modules.task.service.TruckInfoService;
import com.xhtt.modules.task.utils.RestUtils;
import com.xhtt.modules.task.utils.ShipLmModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.http.HttpServletResponse;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;

/**
 * <p>
 * 硬管库 前端控制器
 * </p>
 *
 * @author feipc
 * @since 2019-02-21
 */
@Api(tags = "任务平台-基础数据维护-硬管库列表", value = "任务平台-基础数据维护-硬管库列表")
@RestController
@RequestMapping("app/sys/cfg/tube")
public class CfgTubeInfoController extends AbstractController {

    @Autowired
    private CfgTubeInfoService cfgTubeInfoService;
    @Autowired
    private CfgTubeProductService cfgTubeProductService;
    @Autowired
    private CfgTubeRelateService tubeRelateService;

    @Autowired
    private TaskExecutor taskExecutor;

    /**
     * 获取硬管库列表
     */
    @GetMapping(value = "/list")
    @ApiOperation("获取硬管库列表(web/app)")
    @Login
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = cfgTubeInfoService.queryPage(params);
        return R.ok().put(Constant.DATA, page);
    }

    /**
     * 新增硬管库
     */
    @PostMapping(value = "/add")
    @ApiOperation("新增硬管库(web)")
    @Login
    public R add(@RequestBody CfgTubeInfo cfgTubeInfo) {
        cfgTubeInfoService.add(cfgTubeInfo);
        return R.ok();
    }

    /**
     * 删除硬管库
     */
    @PostMapping(value = "/delete")
    @ApiOperation("删除硬管库(web)")
    @Login
    public R delete(@RequestBody Integer[] ids) {
        //假删除
        CfgTubeInfo t = new CfgTubeInfo();
        t.setStatus(-1);
        cfgTubeInfoService.update(t, new UpdateWrapper<CfgTubeInfo>().in(CfgTubeInfo.ID, Arrays.asList(ids)));
        return R.ok();
    }

    /**
     * 修改硬管库
     */
    @PostMapping(value = "/updateTube")
    @ApiOperation("修改硬管库(web)")
    @Login
    public R updateTube(@RequestBody CfgTubeInfo cfgTubeInfo, @ApiIgnore @LoginUser SysUserEntity user) {
        MDC.put("deptUser", user.getDeptName() + "-" + user.getName());
        cfgTubeInfoService.updateTube(cfgTubeInfo);
        return R.ok();
    }

    /**
     * 获取硬管修改日志
     */
    @GetMapping(value = "/logList")
    @ApiOperation("获取硬管修改日志(web)")
    @Login
    public R logList(@RequestParam Map<String, Object> params) {
        PageUtils page = cfgTubeInfoService.logList(params);
        return R.ok().put(Constant.DATA, page);
    }

    /**
     * 获取硬管库
     */
    @GetMapping(value = "/get/{id}")
    @ApiOperation("获取硬管库(web/app)")
    @Login
    public R get(@PathVariable("id") Integer id) {
        CfgTubeInfo tube = cfgTubeInfoService.getById(id);
        List<CfgTubeProduct> tubeProducts = cfgTubeProductService.list(new LambdaQueryWrapper<CfgTubeProduct>().eq(CfgTubeProduct::getTubeId, tube.getId()));
        tube.setComTubeProduct(tubeProducts.stream().filter(cfgTubeProduct -> cfgTubeProduct.getType().intValue() == 1).collect(Collectors.toList()).get(0));
        tube.setSpareTubeProducts(tubeProducts.stream().filter(cfgTubeProduct -> cfgTubeProduct.getType().intValue() == 2).collect(Collectors.toList()));
        return R.ok().put(Constant.DATA, tube);
    }


    /**
     * 查看硬管连接点
     */
    @GetMapping(value = "/getRelateObject")
    @ApiOperation("查看硬管连接点(web/app)")
    @Login
    public R getRelateObject(@RequestParam Integer tubeId) throws ExecutionException, InterruptedException {
//        ExecutorService executor = Executors.newSingleThreadExecutor();
//        Callable<R> c = () -> {
//            List<CfgTubeRelate> relates = cfgTubeInfoService.getRelateObject(tubeId);
//            return R.ok().put(Constant.DATA, relates);
//        };

//        FutureTask<R> ft = new FutureTask<R>(c);
//        executor.submit(ft);
//        R r = ft.get();

        List<CfgTubeRelate> relates = cfgTubeInfoService.getRelateObject(tubeId);
        return R.ok().put(Constant.DATA, relates);
    }

    /**
     * 排管任务-查看硬管可用的有效的连接点
     */
    @GetMapping(value = "/getValidRelateObject")
    @ApiOperation("排管任务-查看硬管可用的有效的连接点(web)")
    @Login
    public R getValidRelateObject(ValidTubeParam param) {
        List<CfgTubeRelate> relates = tubeRelateService.getValidRelateObject(param);
        List<Integer> selectedPumpIds = param.getSelectedPumpIds();
        List<Integer> selectedTubeIds = param.getSelectedTubeIds();
        if (CollectionUtils.isNotEmpty(selectedPumpIds)) {
            Iterator<CfgTubeRelate> it = relates.iterator();
            while (it.hasNext()) {
                CfgTubeRelate r = it.next();
                if (3 == r.getType().intValue() && selectedPumpIds.contains(r.getRelateId())) {
                    it.remove();
                }
            }
        }
        if (CollectionUtils.isNotEmpty(selectedTubeIds)) {
            Iterator<CfgTubeRelate> it = relates.iterator();
            while (it.hasNext()) {
                CfgTubeRelate r = it.next();
                if (2 == r.getType().intValue() && selectedTubeIds.contains(r.getRelateId())) {
                    it.remove();
                }
            }
        }
        return R.ok().put(Constant.DATA, relates);
    }

    /**
     * 修改硬管连接点
     */
    @PostMapping(value = "/updateRelateObject")
    @ApiOperation("修改硬管连接点(web)")
    @Login
    public R updateRelateObject(@RequestBody List<CfgTubeRelate> relates) {
        cfgTubeInfoService.updateRelateObject(relates);
        return R.ok();
    }

    /**
     * app修改rfid
     */
    @PostMapping(value = "/updateRfid")
    @ApiOperation("app修改rfid(app)")
    @Login
    public R updateRfid(@RequestBody CfgTubeInfo cfgTubeInfo, @ApiIgnore @LoginUser SysUserEntity user) {
        MDC.put("deptUser", user.getDeptName() + "-" + user.getName());
        cfgTubeInfoService.updateRfid(cfgTubeInfo);
        return R.ok();
    }


    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private RestUtils restUtils;
    @Autowired
    private TruckInfoService truckInfoService;

    /**
     * test
     */
    @GetMapping(value = "/sync")
    public R sync() {
        TaskShipTaskLm lm = new TaskShipTaskLm();
        lm.setKb(DateUtils.NA_DATE);
        System.out.println(lm.getKb());
//        ExecutorService executor = Executors.newSingleThreadExecutor();
//        System.out.println(pm.toString());
        Callable<R> c = new Callable<R>() {
            @Override
            public R call() throws Exception {
//                List<CfgTubeRelate> relates = cfgTubeInfoService.getRelateObject(1);
                System.out.println("子线程结束");
                return R.ok().put(Constant.DATA, "fucku");
            }
        };

        FutureTask<R> ft = new FutureTask<R>(c);
        taskExecutor.execute(ft);
//        R r = ft.get();
//        LocalDateTime t = LocalDateTime.now();
//        restUtils.updateShipLMStatus("123",t,t,t,t);
//        String s = restTemplate.getForObject("http://www.baidu.com", String.class);
//        System.out.println(s);

//        truckInfoService.getDataFromTAS(null);

        return R.ok().put("dd", "主线程结束");
    }

    @PostMapping(value = "/upload")
    @ApiOperation("硬管导入")
    public R upload(MultipartFile file) {
        Map<Long, Map<Integer, String>> map = ReadExcel.readExcel(file, 1);
        cfgTubeInfoService.upload(map);
        return R.ok();
    }

    @GetMapping(value = "/mouldExport")
    @ApiOperation("硬管模板下载")
    public void mouldExport(HttpServletResponse response) {
        String fileName = "硬管信息导入模板.xls";
        String path = "templates/outTube.xls";
        DownloadFile.exportFile(fileName, path, response);
    }

    @GetMapping(value = "/export")
    @ApiOperation("硬管导出")
    public void export(HttpServletResponse response, @RequestParam Map<String, Object> params) {
        cfgTubeInfoService.exportExcel(response, params);
    }

    @GetMapping(value = "/logExport")
    @ApiOperation("硬管操作记录导出")
    @Login
    public void logExport(HttpServletResponse response, @RequestParam Map<String, Object> params) {
        ExportExcel exportExcel = new ExportExcel();
        Object tubeId = params.get("id");
        CfgTubeInfo tube = cfgTubeInfoService.getOne(new LambdaQueryWrapper<CfgTubeInfo>().eq(CfgTubeInfo::getId, tubeId).select(CfgTubeInfo::getId, CfgTubeInfo::getNumberNo));
        PageUtils page = cfgTubeInfoService.logList(params);
        List list = page.getList();
        String fileName = "硬管(" + tube.getNumberNo() + ")操作记录";
        String sheetName = "硬管操作记录";
        String[] headers = {"记录时间", "操作人", "目前产品", "备用产品", "RFID"};
        String[] columns = {"createTime", "deptUser", "comProductInfo", "spareProductInfo", "rfidInfo"};
        try {
            exportExcel.exportExcel(fileName, sheetName, headers, columns, list, response);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RRException(RRExceptionEnum.EXPORT_FAIL);
        }
    }
}
